﻿using System;
using System.Drawing;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using DOMercury.Interfaces;
using DOMercury.Items;
using System.Windows.Forms;
using System.ComponentModel;
using System.Web;
using System.Diagnostics;
using System.Text.RegularExpressions;

namespace IEFavoritesPlugin
{
    public class BookmarksItem : IItem, IComparable
    {
        // Fields
        private string desc;
        private string path;

        // Methods
        public BookmarksItem(string Path, string Desc)
        {
            this.path = Path;
            this.desc = Desc;
        }

        public int CompareTo(object obj)
        {
            return this.DisplayName.CompareTo(((IItem)obj).DisplayName);
        }

        // Properties
        public string DisplayDesc
        {
            get
            {
                return this.desc;
            }
        }

        public string DisplayName
        {
            get
            {
                return this.desc;
            }
        }

        public string ItemType
        {
            get
            {
                return "Bookmark";
            }
        }

        public string Path
        {
            get
            {
                return this.path;
            }
        }
    }

    public class BookmarksParentItem : IItem, IComparable
    {
        // Fields
        private List<IItem> bms;
        private List<IconPair> ics;

        // Methods
        public int CompareTo(object obj)
        {
            return this.DisplayName.CompareTo(((IItem)obj).DisplayName);
        }

        public static string First(string s, int charcount)
        {
            if (s == null)
            {
                return string.Empty;
            }
            return s.Substring(0, Math.Min(s.Length, charcount)).ToLower();
        }

        public Bitmap FixBase64ForImage(string Imagestr)
        {
            string str;
            byte[] buffer = new byte[Imagestr.Length];
            StringBuilder builder = new StringBuilder(Imagestr, Imagestr.Length);
            builder.Replace("\r\n", string.Empty);
            builder.Replace(" ", string.Empty);
            if (Imagestr.Length <= 0)
            {
                return null;
            }
            if (builder.ToString().Contains("%"))
            {
                str = HttpUtility.UrlDecode(builder.ToString(), Encoding.UTF8);
            }
            else
            {
                str = builder.ToString();
            }
            MemoryStream stream = new MemoryStream(Convert.FromBase64String(str));
            return new Bitmap((Bitmap)Image.FromStream(stream));
        }

        private List<IItem> GetDocuments()
        {
            try
            {
                this.ReadBookmarks(Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "bookmarks.html", SearchOption.AllDirectories)[0]);
            }
            catch
            {
            }
            return this.bms;
        }

        public Bitmap GetIconFromHref(string StrLine)
        {
            if (StrLine.Contains("ICON="))
            {
                int startIndex = StrLine.IndexOf("ICON=", 0) + 6;
                int index = StrLine.IndexOf("\"", startIndex);
                return this.FixBase64ForImage(StrLine.Substring(startIndex, index - startIndex).Split(new char[] { ',' })[1]);
            }
            return null;
        }

        public static string GetURLFromHref(string StrLine)
        {
            ArrayList list = new ArrayList();
            MatchCollection matchs = new Regex("href\\s*=\\s*(?:(?:\\\"(?<url>[^\\\"]*)\\\")|(?<url>[^\\s]* ))", RegexOptions.IgnoreCase).Matches(StrLine);
            foreach (Match match in matchs)
            {
                string str = match.Groups["URI"].Value.ToString();
                match.Groups["Name"].Value.ToString();
                new Regex(@"http://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?");
                list.Add(str);
            }
            return matchs[0].Groups[1].Value;
        }

        public static string htmlEnt(string strString)
        {
            string str = strString;
            str = strString.Replace("&amp;", "&");
            str = strString.Replace("&lt;", "<");
            str = strString.Replace("&gt;", ">");
            return strString.Replace("&quot;", "\"");
        }

        public void ReadBookmarks(string BookmarkFile)
        {
            this.bms = new List<IItem>();
            this.ics = new List<IconPair>();
            string s = null;
            bool flag = true;
            bool flag2 = false;
            bool flag3 = false;
            int num = 0;
            int num2 = 1;
            StreamReader reader = new StreamReader(BookmarkFile);
            while (!reader.EndOfStream)
            {
                if (!flag2)
                {
                    s = reader.ReadLine();
                    num++;
                }
                else
                {
                    flag2 = false;
                }
                s = s.Replace("\t", "").Trim();
                if (flag)
                {
                    if (First(s, 6) == "<dt><a")
                    {
                        Bitmap iconFromHref;
                        string data = "";
                        string path = "";
                        string str4 = "";
                        data = htmlEnt(StripHTMLTags(s));
                        if (flag3)
                        {
                            data = utfDecode(data);
                        }
                        path = GetURLFromHref(s);
                        try
                        {
                            iconFromHref = this.GetIconFromHref(s);
                        }
                        catch
                        {
                            iconFromHref = new Bitmap(1, 1);
                        }
                        s = reader.ReadLine();
                        num++;
                        s = s.Replace("\t", "").Trim();
                        while ((!(First(s, 4) == "<dt>") && !(First(s, 5) == "</dl>")) && !reader.EndOfStream)
                        {
                            s = Regex.Replace(Regex.Replace(s, "<dd>", string.Empty, RegexOptions.IgnoreCase), "<br>", "\n", RegexOptions.IgnoreCase);
                            if (flag3)
                            {
                                str4 = str4 + htmlEnt(utfDecode(s));
                            }
                            else
                            {
                                str4 = str4 + htmlEnt(s);
                            }
                            s = reader.ReadLine();
                            num++;
                            s = s.Replace("\t", "").Trim();
                        }
                        flag2 = true;
                        if (data != "")
                        {
                            this.bms.Add(new BookmarksItem(path, data));
                            if (iconFromHref != null)
                            {
                                this.ics.Add(new IconPair(data, iconFromHref));
                            }
                            num2++;
                        }
                    }
                    else if ((First(s, "<META HTTP-EQUIV".Length).ToLower() == "<meta http-equiv") && (s.IndexOf("charset=utf-8") != -1))
                    {
                        flag3 = true;
                    }
                }
            }
            reader.Close();
        }

        public static string StripHTMLTags(string StrText)
        {
            return Regex.Replace(StrText, @"<(.|\n)*?>", string.Empty);
        }

        public static string utfDecode(string data)
        {
            string str2;
            try
            {
                Decoder decoder = new UTF8Encoding().GetDecoder();
                byte[] bytes = Convert.FromBase64String(data);
                char[] chars = new char[decoder.GetCharCount(bytes, 0, bytes.Length)];
                decoder.GetChars(bytes, 0, bytes.Length, chars, 0);
                string str = new string(chars);
                str2 = str;
            }
            catch (Exception exception)
            {
                throw new Exception("Error in base64Decode" + exception.Message);
            }
            return str2;
        }

        // Properties
        public List<IItem> Bookmarks
        {
            get
            {
                return this.GetDocuments();
            }
        }

        public string DisplayDesc
        {
            get
            {
                return "Mozilla Firefox.lnk";
            }
        }

        public string DisplayName
        {
            get
            {
                return "Firefox Bookmarks";
            }
        }

        public List<IconPair> Icons
        {
            get
            {
                this.GetDocuments();
                return this.ics;
            }
        }

        public string ItemType
        {
            get
            {
                return "FFBParent";
            }
        }
    }

    [DOMercuryPlugIn("FF Bookmarks Indexing Plugin")]
    public class BookmarksSubIndex : ISubIndex
    {
        // Methods
        public List<IItem> GetSubIndex(IItem item, IAction action)
        {
            return ((BookmarksParentItem)item).Bookmarks;
        }

        public void ShowOptions()
        {
        }

        // Properties
        public string Description
        {
            get
            {
                return "Provides the Firefox Bookmarks as a sub index";
            }
        }

        public bool EnableSearch
        {
            get
            {
                return true;
            }
        }

        public bool HasOptions
        {
            get
            {
                return false;
            }
        }

        public string Name
        {
            get
            {
                return "Firefox Bookmarks Sub Index";
            }
        }

        public string ParentItemType
        {
            get
            {
                return "FFBParent";
            }
        }
    }

    public class Configs
    {
        // Methods
        public static bool ReadSubIndexValue()
        {
            try
            {
                FileStream stream = new FileStream("Plugins/FFBookMsSettings.txt", FileMode.OpenOrCreate, FileAccess.Read);
                StreamReader reader = new StreamReader(stream);
                string str = reader.ReadLine();
                reader.Close();
                stream.Close();
                return (str == "Y");
            }
            catch
            {
                return false;
            }
        }

        public static string ReadBookmarksLocationValue()
        {
            try
            {
                FileStream stream = new FileStream("Plugins/FFBookMsSettings.txt", FileMode.Open, FileAccess.Read);
                StreamReader reader = new StreamReader(stream);
                string str = reader.ReadLine();
                str = reader.ReadLine();
                reader.Close();
                stream.Close();
                return str;
            }
            catch
            {
                return Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "bookmarks.html", SearchOption.AllDirectories)[0];
            }
        }

        public static void WriteSubIndexValue(bool val, string loc)
        {
            try
            {
                FileStream stream = new FileStream("Plugins/FFBookMsSettings.txt", FileMode.OpenOrCreate, FileAccess.Write);
                StreamWriter writer = new StreamWriter(stream);
                if (val)
                {
                    writer.WriteLine("Y");
                }
                else
                {
                    writer.WriteLine("N");
                }
                writer.WriteLine(loc);
                writer.Close();
                stream.Close();
            }
            catch
            {
            }
        }
    }

    [DOMercuryPlugIn("Firefox Bookmarks Indexing Plugin")]
    public class IEFavoritesPlugin : IItemProvider, IActionProvider
    {
        // Fields
        private List<IAction> blanklist = new List<IAction>();
        private List<IconPair> l;

        // Methods
        public IEFavoritesPlugin()
        {
            this.blanklist.Add(new OpenInFFAction());
            this.l = new List<IconPair>();
        }

        public void ShowOptions()
        {
            using (OptionsForm form = new OptionsForm())
            {
                form.BookMarksLocations = Configs.ReadBookmarksLocationValue();
                form.ShowDialog();
            }
        }

        public override string ToString()
        {
            return (this.Name + ": " + this.Description);
        }

        // Properties
        public List<IAction> Actions
        {
            get
            {
                return this.blanklist;
            }
        }

        public List<IconPair> CustomIcons
        {
            get
            {
                return new BookmarksParentItem().Icons;
            }
        }

        public string Description
        {
            get
            {
                return "Indexes all of the user's Firefox Bookmarks";
            }
        }

        public bool HasOptions
        {
            get
            {
                return true;
            }
        }

        public List<IItem> Items
        {
            get
            {
                if (Configs.ReadSubIndexValue())
                {
                    List<IItem> list = new List<IItem>();
                    list.Add(new BookmarksParentItem());
                    return list;
                }

                BookmarksParentItem item = new BookmarksParentItem();
                return item.Bookmarks;
            }
        }

        public string ItemType
        {
            get
            {
                return "Bookmark";
            }
        }

        public string Name
        {
            get
            {
                return "FirefoxBookmarksPlugin";
            }
        }
    }

    public class OpenInFFAction : IAction
    {
        // Methods
        public bool Perform(IItem item, object specialParams)
        {
            try
            {
                Process.Start("firefox", ((BookmarksItem)item).Path);
                return true;
            }
            catch
            {
                return false;
            }
        }

        // Properties
        public string ActionType
        {
            get
            {
                return "Open";
            }
        }

        public string Description
        {
            get
            {
                return "Open the Bookmarked Site in Firefox";
            }
        }

        public string ParamDescription
        {
            get
            {
                return "Unused";
            }
        }

        public string ParameterType
        {
            get
            {
                return "Unused";
            }
        }
    }

}

